package com.example.demo;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.auth0.jwt.JWT;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.example.demo.annot.CheckToken;
import com.example.demo.annot.LoginToken;
import com.example.demo.util.JwtUtil;

public class AuthenticationInterceptor implements HandlerInterceptor {

	@Autowired
	UserService userService;
	
	public boolean preHandle(HttpServletRequest httpServletRequest,
			HttpServletResponse httpServletResponse, Object object) {
		
		String token = httpServletRequest.getHeader("token");
		
		if (!(object instanceof HandlerMethod)) {
			return true;
		}
		
		HandlerMethod handlerMethod = (HandlerMethod) object;
		Method method = handlerMethod.getMethod();
		
		if (method.isAnnotationPresent(LoginToken.class)) {
			LoginToken loginToken = method.getAnnotation(LoginToken.class);
			if (loginToken.required()) {
				return true;
			}
		}
		
		if (method.isAnnotationPresent(CheckToken.class)) {
			CheckToken checkToken = method.getAnnotation(CheckToken.class);
			if (checkToken.required()) {
				if (token == null) {
					throw new RuntimeException("无token, 请重新登录");
				}
				
				String userId;
				try {
					userId = JWT.decode(token).getClaim("id").asString();
				}catch (JWTDecodeException e) {
					throw new RuntimeException("访问异常！");
				}
				User user = userService.findUserById(userId);
				if(user == null) {
					throw new RuntimeException("用户不存在，请重新登录");
				}
				Boolean verify = JwtUtil.isVerify(token, user);
				if (!verify) {
					throw new RuntimeException("非法访问！");
				}
				return true;
			}
		}
		return true;
	}
	
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
			Object o, ModelAndView modeAndView ) throws Exception {
		
	}
}
